﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="LinqToCaml.cs" company="Collaboris Ltd.">
//   Copyright (c) Collaboris Ltd. All rights Reserved.
// </copyright>
// <summary>
//   Defines the LinqToCaml type.
//   TODO: This class is not yet implemented. For help please check the following Blog post: http://blog.wekeroad.com/blog/linq-how-to-use-linq-to-query-just-about-anything
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Collaboris.DataAccess.SharePoint
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;

    /// <summary>
    /// The linq to caml.
    /// </summary>
    /// <typeparam name="T">
    /// </typeparam>
    public class LinqToCaml<T> : IQueryable<T>
    {
        #region Implemented Interfaces

        #region IEnumerable

        /// <summary>
        /// Returns an enumerator that iterates through a collection.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        #region IEnumerable<T>

        /// <summary>
        /// Returns an enumerator that iterates through the collection.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
        /// </returns>
        /// <filterpriority>1</filterpriority>
        public IEnumerator<T> GetEnumerator()
        {
            MethodCallExpression methodCall = this.Expression as MethodCallExpression;
            var xp = (UnaryExpression)methodCall.Arguments[1];
            var lambdaExpression = (LambdaExpression)xp.Operand;
            string camlQuery = this.ProcessExpression(lambdaExpression);

            List<T> items = this.Executequery(camlQuery);

            return items.GetEnumerator();
        }

        #endregion

        #region IQueryable

        /// <summary>
        /// Gets the type of the element(s) that are returned when the expression tree associated with this instance of <see cref="T:System.Linq.IQueryable"/> is executed.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.Type"/> that represents the type of the element(s) that are returned when the expression tree associated with this object is executed.
        /// </returns>
        public Type ElementType
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Gets the expression tree that is associated with the instance of <see cref="T:System.Linq.IQueryable"/>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Linq.Expressions.Expression"/> that is associated with this instance of <see cref="T:System.Linq.IQueryable"/>.
        /// </returns>
        public Expression Expression
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// Gets the query provider that is associated with this data source.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Linq.IQueryProvider"/> that is associated with this data source.
        /// </returns>
        public IQueryProvider Provider
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        #endregion

        #region Helper Methods

        /// <summary>
        /// The executequery.
        /// </summary>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <returns>
        /// </returns>
        private List<T> Executequery(string query)
        {
            // Todo: Executes the caml query using the SPListRepository
            return null;
        }

        /// <summary>
        /// Process the passed-in LINQ expression
        /// </summary>
        /// <param name="expression">
        /// </param>
        /// <returns>
        /// The process expression.
        /// </returns>
        private string ProcessExpression(Expression expression)
        {
            /*
            if (expression.NodeType == ExpressionType.)
            {
                ProcessAndAlso((BinaryExpression)expression);
            }
            else if (expression.NodeType == ExpressionType.Equal)
            {
                ProcessEQ((BinaryExpression)expression);
            }
            else if (expression.NodeType == ExpressionType.LessThan)
            {
                ProcessLessThan((BinaryExpression)expression);
            }
            else if (expression.NodeType == ExpressionType.LessThanOrEqual)
            {
                ProcessLessThan((BinaryExpression)expression);
            }
            else if (expression is MethodCallExpression)
            {
                ProcessMethodCall((MethodCallExpression)expression);
            }
            else if (expression is LambdaExpression)
            {
                ProcessExpression(((LambdaExpression)expression).Body);
            }
            */
            return String.Empty;
        }

        #endregion
    }
}